﻿using Idea.Entity.Collections.Interface;
using Idea.DbContext;
using Idea.Query.Interface;
using Idea.Repository.Collections.Interface;
using Idea.UnitOfWork.Interface;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

namespace Idea.Repository.Collections
{
    public class CollectionRepository : ICollectionRepository
    {
        private IUnitOfWorkManager _manager;
        protected IdeaDbContext context;

        public IUnitOfWorkManager Manager
        {
            get
            {
                return _manager;
            }
            set
            {
                _manager = value;
            }
        }

        public long Count<TCollection>(IQueryObject<TCollection> query) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            var db = context.Collections[typeof(TCollection).Name].Cast<TCollection>();
            return query.Count(db.AsQueryable());
        }

        public IEnumerable<TCollection> Fetch<TCollection>(IQueryObject<TCollection> query) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            var db = context.Collections[typeof(TCollection).Name].Cast<TCollection>();
            return query.Fetch(db.AsQueryable());
        }

        public TCollection FetchOne<TCollection>(IQueryObject<TCollection> query) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            var db = context.Collections[typeof(TCollection).Name].Cast<TCollection>();
            return query.FetchOne(db.AsQueryable());
        }

        public TCollection Find<TCollection>(string id) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            var db = context.Collections[typeof(TCollection).Name];
            return (TCollection)db.Find(id);
        }

        public TCollection Create<TCollection>(TCollection entity) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            return (TCollection)context.Collections[entity.GetType().Name].Add(entity);
        }

        public TCollection Update<TCollection>(TCollection entity) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            var db = context.Collections[typeof(TCollection).Name];
            db.Attach(entity);
            context.Entry(entity).State = EntityState.Modified;
            return entity;
        }

        public void Delete<TCollection>(TCollection entity) where TCollection : class, ICollectionEntity
        {
            ResolveUnitOfWork();
            context.Collections[typeof(TCollection).Name].Remove(entity);
        }



        public IUnitOfWork ResolveUnitOfWork()
        {
            IUnitOfWork uow = _manager.GetCurrentUnitOfWork();
            context = (IdeaDbContext)uow.DbContext;

            return uow;
        }
    }
}
